/**************************************************************************************
*  RTC.c
*
*  This file defines all native methods that have to be implemented to support
*  the class lpc2xxx/hw/RTC
*
*  Application developer should use the following functions to get access to
*  arrays and String object:
*       vmGetStringCount
*       vmGetStringArray
*       vmGetArraySize
*       vmGetArray
*  These functions are accessible via vm_config_t structure.
*
*  Native methods implementation
*  -----------------------------
*  Note that if the native method is NOT declared as static then param[0]
*  contains object's reference and must be skiped when accessing the native
*  method parameters.
**************************************************************************************
*
* This file is covered by the GNU GPL with the following exception:
*   As a special exception, the copyright holders of this library give you permission
*   to link this library with independent modules to produce an executable, regardless
*   of the license terms of these independent modules, and to copy and distribute the
*   resulting executable under terms of your choice, provided that you also meet, for
*   each linked independent module, the terms and conditions of the license of that
*   module. An independent module is a module which is not derived from or based on
*   this library. If you modify this library, you may extend this exception to your
*   version of the library, but you are not obligated to do so. If you do not wish
*   to do so, delete this exception statement from your version.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL RTJ COMPUTING BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Copyright (c) 2000-2006 RTJ Computing Pty. Ltd. All rights reserved.
**************************************************************************************/
#include <lpc2xxx.h>
#include "startup/config.h"
#include "javavm.h"

extern vm_config_t vmconfig;

#define CRYSTAL_FREQUENCY FOSC
#define PLL_FACTOR        PLL_MUL
#define VPBDIV_FACTOR     PBSD

#define R_HOUR    1
#define R_MIN     2
#define R_SEC     3
#define R_YEAR    4
#define R_MON     5
#define R_DAY     6
#define R_DOW     7

/****************************************************************************
* Initialises the RTC.
* On entry: param[0] - true if RTC is driven by an external 32.768 kHz crystal.
*
* Java prototype:
*   public static native void init(boolean use32kCrystal);
*
****************************************************************************/
int16 lpc2xxx_hw_RTC_init(int32 param[], int32 *retval)
{
    RTC_CCR  = 0x00000002;   // reset clock
    RTC_ILR  = 0x00000000;   // clear interrupt flags
    RTC_CIIR = 0x00000001;   // set interrupt flag once each second
    RTC_AMR  = 0x000000FF;   // do not compare any alarm
  
    if (param[0] == 0) {
        RTC_PREINT  = ((CRYSTAL_FREQUENCY * PLL_FACTOR) / VPBDIV_FACTOR) / 32768 - 1;
        RTC_PREFRAC = ((CRYSTAL_FREQUENCY * PLL_FACTOR) / VPBDIV_FACTOR) - 
                      (((CRYSTAL_FREQUENCY * PLL_FACTOR) / VPBDIV_FACTOR) / 32768) * 32768;
        //start real-time clock, use core clock
        RTC_CCR  = 0x00000001;   
    }
    else
        RTC_CCR  = 0x00000011;   //start real-time clock, use 32kHz crystal

    return NO_EXCEP;
}

/****************************************************************************
* Sets the new value for specified RTC date/time register.
* On entry: param[0] - identifies date/time register
*           param[1] - new value that will be written to date/time register
*
* Java prototype:
*   private static native void set(int id, int val);
*
****************************************************************************/
int16 lpc2xxx_hw_RTC_set(int32 param[], int32 *retval)
{
    int8 v = (int8)param[1];
    switch (param[0]) {
        case R_HOUR:
            if (v >= 0 && v <= 23)
                RTC_HOUR = v;
            break;
        case R_MIN:
            if (v >= 0 && v <= 59)
                RTC_MIN = v;
            break;
        case R_SEC:
            if (v >= 0 && v <= 59)
                RTC_SEC = v;
            break;
        case R_YEAR:
            RTC_YEAR = param[1];
            break;
        case R_MON:
            if (v >= 1 && v <= 12)
                RTC_MONTH = v;
            break;
        case R_DAY:
            if (v >= 1 && v <= 31)
                RTC_DOM = v;
            break;
        case R_DOW:
            if (v >= 0 && v <= 6)
                RTC_DOW = v;
            break;
    }

    return NO_EXCEP;
}

/****************************************************************************
* Get the current value from specified RTC date/time register.
* On entry: param[0] - identifies date/time register
*
* On return: retval contains requested value of date/time register.
*
* Java prototype:
*   private static native int get(int id);
*
****************************************************************************/
int16 lpc2xxx_hw_RTC_get(int32 param[], int32 *retval)
{
    *retval = 0;
    switch (param[0]) {
        case R_HOUR:
            *retval = RTC_HOUR;
            break;
        case R_MIN:
            *retval = RTC_MIN;
            break;
        case R_SEC:
            *retval = RTC_SEC;
            break;
        case R_YEAR:
            *retval = RTC_YEAR;
            break;
        case R_MON:
            *retval = RTC_MONTH;
            break;
        case R_DAY:
            *retval = RTC_DOM;
            break;
        case R_DOW:
            *retval = RTC_DOW;
            break;
    }

    return NO_EXCEP;
}


